home *** CD-ROM | disk | FTP | other *** search
/ Clickx 96 / Clickx 96.iso / software / tools / tool / xbmc-10.1.exe / addons / script.module.pil / lib / PIL / ImageCms.py < prev    next >
Encoding:
Python Source  |  2009-04-06  |  30.4 KB  |  787 lines

  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # optional color managment support, based on Kevin Cazabon's PyCMS
  6. # library.
  7. #
  8. # History:
  9. # 2009-03-08 fl   Added to PIL.
  10. #
  11. # Copyright (C) 2002-2003 Kevin Cazabon
  12. # Copyright (c) 2009 by Fredrik Lundh
  13. #
  14. # See the README file for information on usage and redistribution.  See
  15. # below for the original description.
  16. #
  17.  
  18. DESCRIPTION = """
  19. pyCMS
  20.  
  21.     a Python / PIL interface to the littleCMS ICC Color Management System
  22.     Copyright (C) 2002-2003 Kevin Cazabon
  23.     kevin@cazabon.com
  24.     http://www.cazabon.com
  25.  
  26.     pyCMS home page:  http://www.cazabon.com/pyCMS
  27.     littleCMS home page:  http://www.littlecms.com
  28.     (littleCMS is Copyright (C) 1998-2001 Marti Maria)
  29.  
  30.     Originally released under LGPL.  Graciously donated to PIL in
  31.     March 2009, for distribution under the standard PIL license
  32.  
  33.     The pyCMS.py module provides a "clean" interface between Python/PIL and
  34.     pyCMSdll, taking care of some of the more complex handling of the direct
  35.     pyCMSdll functions, as well as error-checking and making sure that all
  36.     relevant data is kept together.
  37.  
  38.     While it is possible to call pyCMSdll functions directly, it's not highly
  39.     recommended.
  40.  
  41.     Version History:
  42.  
  43.         0.1.0 pil mod   March 10, 2009
  44.  
  45.                         Renamed display profile to proof profile. The proof
  46.                         profile is the profile of the device that is being
  47.                         simulated, not the profile of the device which is
  48.                         actually used to display/print the final simulation
  49.                         (that'd be the output profile) - also see LCMSAPI.txt
  50.                         input colorspace -> using 'renderingIntent' -> proof
  51.                         colorspace -> using 'proofRenderingIntent' -> output
  52.                         colorspace
  53.  
  54.                         Added LCMS FLAGS support.
  55.                         Added FLAGS["SOFTPROOFING"] as default flag for
  56.                         buildProofTransform (otherwise the proof profile/intent
  57.                         would be ignored).
  58.  
  59.         0.1.0 pil       March 2009 - added to PIL, as PIL.ImageCms
  60.  
  61.         0.0.2 alpha     Jan 6, 2002
  62.  
  63.                         Added try/except statements arount type() checks of
  64.                         potential CObjects... Python won't let you use type()
  65.                         on them, and raises a TypeError (stupid, if you ask me!)
  66.  
  67.                         Added buildProofTransformFromOpenProfiles() function.
  68.                         Additional fixes in DLL, see DLL code for details.
  69.  
  70.         0.0.1 alpha     first public release, Dec. 26, 2002
  71.  
  72.     Known to-do list with current version (of Python interface, not pyCMSdll):
  73.  
  74.         none
  75.  
  76. """
  77.  
  78. VERSION = "0.1.0 pil"
  79.  
  80. # --------------------------------------------------------------------.
  81.  
  82. import Image
  83. import _imagingcms
  84.  
  85. core = _imagingcms
  86.  
  87. #
  88. # intent/direction values
  89.  
  90. INTENT_PERCEPTUAL = 0
  91. INTENT_RELATIVE_COLORIMETRIC = 1
  92. INTENT_SATURATION = 2
  93. INTENT_ABSOLUTE_COLORIMETRIC = 3
  94.  
  95. DIRECTION_INPUT = 0
  96. DIRECTION_OUTPUT = 1
  97. DIRECTION_PROOF = 2
  98.  
  99. #
  100. # flags
  101.  
  102. FLAGS = {
  103.     "MATRIXINPUT": 1,
  104.     "MATRIXOUTPUT": 2,
  105.     "MATRIXONLY": (1|2),
  106.     "NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot
  107.     "NOPRELINEARIZATION": 16, # Don't create prelinearization tables on precalculated transforms (internal use)
  108.     "GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink)
  109.     "NOTCACHE": 64, # Inhibit 1-pixel cache
  110.     "NOTPRECALC": 256,
  111.     "NULLTRANSFORM": 512, # Don't transform anyway
  112.     "HIGHRESPRECALC": 1024, # Use more memory to give better accurancy
  113.     "LOWRESPRECALC": 2048, # Use less memory to minimize resouces
  114.     "WHITEBLACKCOMPENSATION": 8192,
  115.     "BLACKPOINTCOMPENSATION": 8192,
  116.     "GAMUTCHECK": 4096, # Out of Gamut alarm
  117.     "SOFTPROOFING": 16384, # Do softproofing
  118.     "PRESERVEBLACK": 32768, # Black preservation
  119.     "NODEFAULTRESOURCEDEF": 16777216, # CRD special
  120.     "GRIDPOINTS": lambda n: ((n) & 0xFF) << 16 # Gridpoints
  121. }
  122.  
  123. _MAX_FLAG = 0
  124. for flag in FLAGS.values():
  125.     if isinstance(flag, type(0)):
  126.         _MAX_FLAG = _MAX_FLAG | flag
  127.  
  128. # --------------------------------------------------------------------.
  129. # Experimental PIL-level API
  130. # --------------------------------------------------------------------.
  131.  
  132. ##
  133. # Profile.
  134.  
  135. class ImageCmsProfile:
  136.  
  137.     def __init__(self, profile):
  138.         # accepts a string (filename), a file-like object, or a low-level
  139.         # profile object
  140.         if Image.isStringType(profile):
  141.             self._set(core.profile_open(profile), profile)
  142.         elif hasattr(profile, "read"):
  143.             self._set(core.profile_fromstring(profile.read()))
  144.         else:
  145.             self._set(profile) # assume it's already a profile
  146.  
  147.     def _set(self, profile, filename=None):
  148.         self.profile = profile
  149.         self.filename = filename
  150.         if profile:
  151.             self.product_name = profile.product_name
  152.             self.product_info = profile.product_info
  153.         else:
  154.             self.product_name = None
  155.             self.product_info = None
  156.  
  157. ##
  158. # Transform.  This can be used with the procedural API, or with the
  159. # standard {@link Image.point} method.
  160.  
  161. class ImageCmsTransform(Image.ImagePointHandler):
  162.  
  163.     def __init__(self, input, output, input_mode, output_mode,
  164.                  intent=INTENT_PERCEPTUAL,
  165.                  proof=None, proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0):
  166.         if proof is None:
  167.             self.transform = core.buildTransform(
  168.                 input.profile, output.profile,
  169.                 input_mode, output_mode,
  170.                 intent,
  171.                 flags
  172.                 )
  173.         else:
  174.             self.transform = core.buildProofTransform(
  175.                 input.profile, output.profile, proof.profile,
  176.                 input_mode, output_mode,
  177.                 intent, proof_intent,
  178.                 flags
  179.                 )
  180.         # Note: inputMode and outputMode are for pyCMS compatibility only
  181.         self.input_mode = self.inputMode = input_mode
  182.         self.output_mode = self.outputMode = output_mode
  183.  
  184.     def point(self, im):
  185.         return self.apply(im)
  186.  
  187.     def apply(self, im, imOut=None):
  188.         im.load()
  189.         if imOut is None:
  190.             imOut = Image.new(self.output_mode, im.size, None)
  191.         result = self.transform.apply(im.im.id, imOut.im.id)
  192.         return imOut
  193.  
  194.     def apply_in_place(self, im):
  195.         im.load()
  196.         if im.mode != self.output_mode:
  197.             raise ValueError("mode mismatch") # wrong output mode
  198.         result = self.transform.apply(im.im.id, im.im.id)
  199.         return im
  200.  
  201. ##
  202. # (experimental) Fetches the profile for the current display device.
  203. # Returns None if the profile is not known.
  204.  
  205. def get_display_profile(handle=None):
  206.     import sys
  207.     if sys.platform == "win32":
  208.         import ImageWin
  209.         if isinstance(handle, ImageWin.HDC):
  210.             profile = core.get_display_profile_win32(handle, 1)
  211.         else:
  212.             profile = core.get_display_profile_win32(handle or 0)
  213.     else:
  214.         try:
  215.             get = _imagingcms.get_display_profile
  216.         except AttributeError:
  217.             return None
  218.         else:
  219.             profile = get()
  220.     return ImageCmsProfile(profile)
  221.  
  222. # --------------------------------------------------------------------.
  223. # pyCMS compatible layer
  224. # --------------------------------------------------------------------.
  225.  
  226. ##
  227. # (pyCMS) Exception class.  This is used for all errors in the pyCMS API.
  228.  
  229. class PyCMSError(Exception):
  230.     pass
  231.  
  232. ##
  233. # (pyCMS) Applies an ICC transformation to a given image, mapping from
  234. # inputProfile to outputProfile.
  235.  
  236. def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL, outputMode=None, inPlace=0, flags=0):
  237.     """
  238.     ImageCms.profileToProfile(im, inputProfile, outputProfile,
  239.         [renderingIntent], [outputMode], [inPlace])
  240.  
  241.     Returns either None or a new PIL image object, depending on value of
  242.     inPlace (see below).
  243.  
  244.     im = an open PIL image object (i.e. Image.new(...) or
  245.         Image.open(...), etc.)
  246.     inputProfile = string, as a valid filename path to the ICC input
  247.         profile you wish to use for this image, or a profile object
  248.     outputProfile = string, as a valid filename path to the ICC output
  249.         profile you wish to use for this image, or a profile object
  250.     renderingIntent = integer (0-3) specifying the rendering intent you
  251.         wish to use for the transform
  252.         INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
  253.         INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
  254.         INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
  255.         INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
  256.  
  257.         see the pyCMS documentation for details on rendering intents and
  258.         what they do.
  259.     outputMode = a valid PIL mode for the output image (i.e. "RGB", "CMYK",
  260.         etc.).  Note: if rendering the image "inPlace", outputMode MUST be
  261.         the same mode as the input, or omitted completely.  If omitted, the
  262.         outputMode will be the same as the mode of the input image (im.mode)
  263.     inPlace = BOOL (1 = TRUE, None or 0 = FALSE).  If TRUE, the original
  264.         image is modified in-place, and None is returned.  If FALSE
  265.         (default), a new Image object is returned with the transform
  266.         applied.
  267.     flags = integer (0-...) specifying additional flags
  268.  
  269.     If the input or output profiles specified are not valid filenames, a
  270.     PyCMSError will be raised.  If inPlace == TRUE and outputMode != im.mode,
  271.     a PyCMSError will be raised.  If an error occurs during application of
  272.     the profiles, a PyCMSError will be raised.  If outputMode is not a mode
  273.     supported by the outputProfile (or by pyCMS), a PyCMSError will be
  274.     raised.
  275.  
  276.     This function applies an ICC transformation to im from inputProfile's
  277.     color space to outputProfile's color space using the specified rendering
  278.     intent to decide how to handle out-of-gamut colors.
  279.  
  280.     OutputMode can be used to specify that a color mode conversion is to
  281.     be done using these profiles, but the specified profiles must be able
  282.     to handle that mode.  I.e., if converting im from RGB to CMYK using
  283.     profiles, the input profile must handle RGB data, and the output
  284.     profile must handle CMYK data.
  285.  
  286.     """
  287.  
  288.     if outputMode is None:
  289.         outputMode = im.mode
  290.  
  291.     if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
  292.         raise PyCMSError("renderingIntent must be an integer between 0 and 3")
  293.  
  294.     if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
  295.         raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
  296.  
  297.     try:
  298.         if not isinstance(inputProfile, ImageCmsProfile):
  299.             inputProfile = ImageCmsProfile(inputProfile)
  300.         if not isinstance(outputProfile, ImageCmsProfile):
  301.             outputProfile = ImageCmsProfile(outputProfile)
  302.         transform = ImageCmsTransform(
  303.             inputProfile, outputProfile, im.mode, outputMode, renderingIntent, flags=flags
  304.             )
  305.         if inPlace:
  306.             transform.apply_in_place(im)
  307.             imOut = None
  308.         else:
  309.             imOut = transform.apply(im)
  310.     except (IOError, TypeError, ValueError), v:
  311.         raise PyCMSError(v)
  312.  
  313.     return imOut
  314.  
  315. ##
  316. # (pyCMS) Opens an ICC profile file.
  317.  
  318. def getOpenProfile(profileFilename):
  319.     """
  320.     ImageCms.getOpenProfile(profileFilename)
  321.  
  322.     Returns a CmsProfile class object.
  323.  
  324.     profileFilename = string, as a valid filename path to the ICC profile
  325.         you wish to open, or a file-like object.
  326.  
  327.     The PyCMSProfile object can be passed back into pyCMS for use in creating
  328.     transforms and such (as in ImageCms.buildTransformFromOpenProfiles()).
  329.  
  330.     If profileFilename is not a vaild filename for an ICC profile, a
  331.     PyCMSError will be raised.
  332.  
  333.     """
  334.  
  335.     try:
  336.         return ImageCmsProfile(profileFilename)
  337.     except (IOError, TypeError, ValueError), v:
  338.         raise PyCMSError(v)
  339.  
  340. ##
  341. # (pyCMS) Builds an ICC transform mapping from the inputProfile to the
  342. # outputProfile.  Use applyTransform to apply the transform to a given
  343. # image.
  344.  
  345. def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, flags=0):
  346.     """
  347.     ImageCms.buildTransform(inputProfile, outputProfile, inMode, outMode,
  348.         [renderingIntent])
  349.  
  350.     Returns a CmsTransform class object.
  351.  
  352.     inputProfile = string, as a valid filename path to the ICC input
  353.         profile you wish to use for this transform, or a profile object
  354.     outputProfile = string, as a valid filename path to the ICC output
  355.         profile you wish to use for this transform, or a profile object
  356.     inMode = string, as a valid PIL mode that the appropriate profile also
  357.         supports (i.e. "RGB", "RGBA", "CMYK", etc.)
  358.     outMode = string, as a valid PIL mode that the appropriate profile also
  359.         supports (i.e. "RGB", "RGBA", "CMYK", etc.)
  360.     renderingIntent = integer (0-3) specifying the rendering intent you
  361.         wish to use for the transform
  362.         INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
  363.         INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
  364.         INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
  365.         INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
  366.         see the pyCMS documentation for details on rendering intents and
  367.         what they do.
  368.     flags = integer (0-...) specifying additional flags
  369.  
  370.     If the input or output profiles specified are not valid filenames, a
  371.     PyCMSError will be raised.  If an error occurs during creation of the
  372.     transform, a PyCMSError will be raised.
  373.  
  374.     If inMode or outMode are not a mode supported by the outputProfile (or
  375.     by pyCMS), a PyCMSError will be raised.
  376.  
  377.     This function builds and returns an ICC transform from the inputProfile
  378.     to the outputProfile using the renderingIntent to determine what to do
  379.     with out-of-gamut colors.  It will ONLY work for converting images that
  380.     are in inMode to images that are in outMode color format (PIL mode,
  381.     i.e. "RGB", "RGBA", "CMYK", etc.).
  382.  
  383.     Building the transform is a fair part of the overhead in
  384.     ImageCms.profileToProfile(), so if you're planning on converting multiple
  385.     images using the same input/output settings, this can save you time.
  386.     Once you have a transform object, it can be used with
  387.     ImageCms.applyProfile() to convert images without the need to re-compute
  388.     the lookup table for the transform.
  389.  
  390.     The reason pyCMS returns a class object rather than a handle directly
  391.     to the transform is that it needs to keep track of the PIL input/output
  392.     modes that the transform is meant for.  These attributes are stored in
  393.     the "inMode" and "outMode" attributes of the object (which can be
  394.     manually overridden if you really want to, but I don't know of any
  395.     time that would be of use, or would even work).
  396.  
  397.     """
  398.  
  399.     if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
  400.         raise PyCMSError("renderingIntent must be an integer between 0 and 3")
  401.  
  402.     if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
  403.         raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
  404.  
  405.     try:
  406.         if not isinstance(inputProfile, ImageCmsProfile):
  407.             inputProfile = ImageCmsProfile(inputProfile)
  408.         if not isinstance(outputProfile, ImageCmsProfile):
  409.             outputProfile = ImageCmsProfile(outputProfile)
  410.         return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags)
  411.     except (IOError, TypeError, ValueError), v:
  412.         raise PyCMSError(v)
  413.  
  414. ##
  415. # (pyCMS) Builds an ICC transform mapping from the inputProfile to the
  416. # outputProfile, but tries to simulate the result that would be
  417. # obtained on the proofProfile device.
  418.  
  419. def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC, flags=FLAGS["SOFTPROOFING"]):
  420.     """
  421.     ImageCms.buildProofTransform(inputProfile, outputProfile, proofProfile,
  422.         inMode, outMode, [renderingIntent], [proofRenderingIntent])
  423.  
  424.     Returns a CmsTransform class object.
  425.  
  426.     inputProfile = string, as a valid filename path to the ICC input
  427.         profile you wish to use for this transform, or a profile object
  428.     outputProfile = string, as a valid filename path to the ICC output
  429.         (monitor, usually) profile you wish to use for this transform,
  430.         or a profile object
  431.     proofProfile = string, as a valid filename path to the ICC proof
  432.         profile you wish to use for this transform, or a profile object
  433.     inMode = string, as a valid PIL mode that the appropriate profile also
  434.         supports (i.e. "RGB", "RGBA", "CMYK", etc.)
  435.     outMode = string, as a valid PIL mode that the appropriate profile also
  436.         supports (i.e. "RGB", "RGBA", "CMYK", etc.)
  437.     renderingIntent = integer (0-3) specifying the rendering intent you
  438.         wish to use for the input->proof (simulated) transform
  439.         INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
  440.         INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
  441.         INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
  442.         INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
  443.         see the pyCMS documentation for details on rendering intents and
  444.         what they do.
  445.     proofRenderingIntent = integer (0-3) specifying the rendering intent
  446.         you wish to use for proof->output transform
  447.         INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
  448.         INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
  449.         INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
  450.         INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
  451.         see the pyCMS documentation for details on rendering intents and
  452.         what they do.
  453.     flags = integer (0-...) specifying additional flags
  454.  
  455.     If the input, output, or proof profiles specified are not valid
  456.     filenames, a PyCMSError will be raised.
  457.  
  458.     If an error occurs during creation of the transform, a PyCMSError will
  459.     be raised.
  460.  
  461.     If inMode or outMode are not a mode supported by the outputProfile
  462.     (or by pyCMS), a PyCMSError will be raised.
  463.  
  464.     This function builds and returns an ICC transform from the inputProfile
  465.     to the outputProfile, but tries to simulate the result that would be
  466.     obtained on the proofProfile device using renderingIntent and
  467.     proofRenderingIntent to determine what to do with out-of-gamut
  468.     colors.  This is known as "soft-proofing".  It will ONLY work for
  469.     converting images that are in inMode to images that are in outMode
  470.     color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.).
  471.  
  472.     Usage of the resulting transform object is exactly the same as with
  473.     ImageCms.buildTransform().
  474.  
  475.     Proof profiling is generally used when using an output device to get a
  476.     good idea of what the final printed/displayed image would look like on
  477.     the proofProfile device when it's quicker and easier to use the
  478.     output device for judging color.  Generally, this means that the
  479.     output device is a monitor, or a dye-sub printer (etc.), and the simulated
  480.     device is something more expensive, complicated, or time consuming
  481.     (making it difficult to make a real print for color judgement purposes).
  482.  
  483.     Soft-proofing basically functions by adjusting the colors on the
  484.     output device to match the colors of the device being simulated. However,
  485.     when the simulated device has a much wider gamut than the output
  486.     device, you may obtain marginal results.
  487.  
  488.     """
  489.  
  490.     if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
  491.         raise PyCMSError("renderingIntent must be an integer between 0 and 3")
  492.  
  493.     if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
  494.         raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
  495.  
  496.     try:
  497.         if not isinstance(inputProfile, ImageCmsProfile):
  498.             inputProfile = ImageCmsProfile(inputProfile)
  499.         if not isinstance(outputProfile, ImageCmsProfile):
  500.             outputProfile = ImageCmsProfile(outputProfile)
  501.         if not isinstance(proofProfile, ImageCmsProfile):
  502.             proofProfile = ImageCmsProfile(proofProfile)
  503.         return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags)
  504.     except (IOError, TypeError, ValueError), v:
  505.         raise PyCMSError(v)
  506.  
  507. buildTransformFromOpenProfiles = buildTransform
  508. buildProofTransformFromOpenProfiles = buildProofTransform
  509.  
  510. ##
  511. # (pyCMS) Applies a transform to a given image.
  512.  
  513. def applyTransform(im, transform, inPlace=0):
  514.     """
  515.     ImageCms.applyTransform(im, transform, [inPlace])
  516.  
  517.     Returns either None, or a new PIL Image object, depending on the value
  518.         of inPlace (see below)
  519.  
  520.     im = a PIL Image object, and im.mode must be the same as the inMode
  521.         supported by the transform.
  522.     transform = a valid CmsTransform class object
  523.     inPlace = BOOL (1 == TRUE, 0 or None == FALSE).  If TRUE, im is
  524.         modified in place and None is returned, if FALSE, a new Image
  525.         object with the transform applied is returned (and im is not
  526.         changed).  The default is FALSE.
  527.  
  528.     If im.mode != transform.inMode, a PyCMSError is raised.
  529.  
  530.     If inPlace == TRUE and transform.inMode != transform.outMode, a
  531.     PyCMSError is raised.
  532.  
  533.     If im.mode, transfer.inMode, or transfer.outMode is not supported by
  534.     pyCMSdll or the profiles you used for the transform, a PyCMSError is
  535.     raised.
  536.  
  537.     If an error occurs while the transform is being applied, a PyCMSError
  538.     is raised.
  539.  
  540.     This function applies a pre-calculated transform (from
  541.     ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) to an
  542.     image.  The transform can be used for multiple images, saving
  543.     considerable calcuation time if doing the same conversion multiple times.
  544.  
  545.     If you want to modify im in-place instead of receiving a new image as
  546.     the return value, set inPlace to TRUE.  This can only be done if
  547.     transform.inMode and transform.outMode are the same, because we can't
  548.     change the mode in-place (the buffer sizes for some modes are
  549.     different).  The  default behavior is to return a new Image object of
  550.     the same dimensions in mode transform.outMode.
  551.  
  552.     """
  553.  
  554.     try:
  555.         if inPlace:
  556.             transform.apply_in_place(im)
  557.             imOut = None
  558.         else:
  559.             imOut = transform.apply(im)
  560.     except (TypeError, ValueError), v:
  561.         raise PyCMSError(v)
  562.  
  563.     return imOut
  564.  
  565. ##
  566. # (pyCMS) Creates a profile.
  567.  
  568. def createProfile(colorSpace, colorTemp=-1):
  569.     """
  570.     ImageCms.createProfile(colorSpace, [colorTemp])
  571.  
  572.     Returns a CmsProfile class object
  573.  
  574.     colorSpace = string, the color space of the profile you wish to create.
  575.         Currently only "LAB", "XYZ", and "sRGB" are supported.
  576.     colorTemp = positive integer for the white point for the profile, in
  577.         degrees Kelvin (i.e. 5000, 6500, 9600, etc.).  The default is for
  578.         D50 illuminant if omitted (5000k).  colorTemp is ONLY applied to
  579.         LAB profiles, and is ignored for XYZ and sRGB.
  580.  
  581.     If colorSpace not in ["LAB", "XYZ", "sRGB"], a PyCMSError is raised
  582.  
  583.     If using LAB and colorTemp != a positive integer, a PyCMSError is raised.
  584.  
  585.     If an error occurs while creating the profile, a PyCMSError is raised.
  586.  
  587.     Use this function to create common profiles on-the-fly instead of
  588.     having to supply a profile on disk and knowing the path to it.  It
  589.     returns a normal CmsProfile object that can be passed to
  590.     ImageCms.buildTransformFromOpenProfiles() to create a transform to apply
  591.     to images.
  592.  
  593.     """
  594.     if colorSpace not in ["LAB", "XYZ", "sRGB"]:
  595.         raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace)
  596.  
  597.     if colorSpace == "LAB":
  598.         if type(colorTemp) == type(5000.0):
  599.             colorTemp = int(colorTemp + 0.5)
  600.         if type (colorTemp) != type (5000):
  601.             raise PyCMSError("Color temperature must be a positive integer, \"%s\" not valid" % colorTemp)
  602.  
  603.     try:
  604.         return core.createProfile(colorSpace, colorTemp)
  605.     except (TypeError, ValueError), v:
  606.         raise PyCMSError(v)
  607.  
  608. ##
  609. # (pyCMS) Gets the internal product name for the given profile.
  610.  
  611. def getProfileName(profile):
  612.     """
  613.     ImageCms.getProfileName(profile)
  614.  
  615.     Returns a string containing the internal name of the profile as stored
  616.         in an ICC tag.
  617.  
  618.     profile = EITHER a valid CmsProfile object, OR a string of the
  619.         filename of an ICC profile.
  620.  
  621.     If profile isn't a valid CmsProfile object or filename to a profile,
  622.     a PyCMSError is raised If an error occurs while trying to obtain the
  623.     name tag, a PyCMSError is raised.
  624.  
  625.     Use this function to obtain the INTERNAL name of the profile (stored
  626.     in an ICC tag in the profile itself), usually the one used when the
  627.     profile was originally created.  Sometimes this tag also contains
  628.     additional information supplied by the creator.
  629.  
  630.     """
  631.     try:
  632.         # add an extra newline to preserve pyCMS compatibility
  633.         if not isinstance(profile, ImageCmsProfile):
  634.             profile = ImageCmsProfile(profile)
  635.         return profile.profile.product_name + "\n"
  636.     except (AttributeError, IOError, TypeError, ValueError), v:
  637.         raise PyCMSError(v)
  638.  
  639. ##
  640. # (pyCMS) Gets the internal product information for the given profile.
  641.  
  642. def getProfileInfo(profile):
  643.     """
  644.     ImageCms.getProfileInfo(profile)
  645.  
  646.     Returns a string containing the internal profile information stored in
  647.         an ICC tag.
  648.  
  649.     profile = EITHER a valid CmsProfile object, OR a string of the
  650.         filename of an ICC profile.
  651.  
  652.     If profile isn't a valid CmsProfile object or filename to a profile,
  653.     a PyCMSError is raised.
  654.  
  655.     If an error occurs while trying to obtain the info tag, a PyCMSError
  656.     is raised
  657.  
  658.     Use this function to obtain the information stored in the profile's
  659.     info tag.  This often contains details about the profile, and how it
  660.     was created, as supplied by the creator.
  661.  
  662.     """
  663.     try:
  664.         if not isinstance(profile, ImageCmsProfile):
  665.             profile = ImageCmsProfile(profile)
  666.         # add an extra newline to preserve pyCMS compatibility
  667.         return profile.product_info + "\n"
  668.     except (AttributeError, IOError, TypeError, ValueError), v:
  669.         raise PyCMSError(v)
  670.  
  671. ##
  672. # (pyCMS) Gets the default intent name for the given profile.
  673.  
  674. def getDefaultIntent(profile):
  675.     """
  676.     ImageCms.getDefaultIntent(profile)
  677.  
  678.     Returns integer 0-3 specifying the default rendering intent for this
  679.         profile.
  680.         INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
  681.         INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
  682.         INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
  683.         INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
  684.         see the pyCMS documentation for details on rendering intents and
  685.         what they do.
  686.  
  687.     profile = EITHER a valid CmsProfile object, OR a string of the
  688.         filename of an ICC profile.
  689.  
  690.     If profile isn't a valid CmsProfile object or filename to a profile,
  691.     a PyCMSError is raised.
  692.  
  693.     If an error occurs while trying to obtain the default intent, a
  694.     PyCMSError is raised.
  695.  
  696.     Use this function to determine the default (and usually best optomized)
  697.     rendering intent for this profile.  Most profiles support multiple
  698.     rendering intents, but are intended mostly for one type of conversion.
  699.     If you wish to use a different intent than returned, use
  700.     ImageCms.isIntentSupported() to verify it will work first.
  701.     """
  702.     try:
  703.         if not isinstance(profile, ImageCmsProfile):
  704.             profile = ImageCmsProfile(profile)
  705.         return profile.profile.rendering_intent
  706.     except (AttributeError, IOError, TypeError, ValueError), v:
  707.         raise PyCMSError(v)
  708.  
  709. ##
  710. # (pyCMS) Checks if a given intent is supported.
  711.  
  712. def isIntentSupported(profile, intent, direction):
  713.     """
  714.     ImageCms.isIntentSupported(profile, intent, direction)
  715.  
  716.     Returns 1 if the intent/direction are supported, -1 if they are not.
  717.  
  718.     profile = EITHER a valid CmsProfile object, OR a string of the
  719.         filename of an ICC profile.
  720.     intent = integer (0-3) specifying the rendering intent you wish to use
  721.         with this profile
  722.         INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
  723.         INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
  724.         INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
  725.         INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
  726.         see the pyCMS documentation for details on rendering intents and
  727.         what they do.
  728.     direction = integer specifing if the profile is to be used for input,
  729.         output, or proof
  730.         INPUT =               0 (or use ImageCms.DIRECTION_INPUT)
  731.         OUTPUT =              1 (or use ImageCms.DIRECTION_OUTPUT)
  732.         PROOF =               2 (or use ImageCms.DIRECTION_PROOF)
  733.  
  734.     Use this function to verify that you can use your desired
  735.     renderingIntent with profile, and that profile can be used for the
  736.     input/output/proof profile as you desire.
  737.  
  738.     Some profiles are created specifically for one "direction", can cannot
  739.     be used for others.  Some profiles can only be used for certain
  740.     rendering intents... so it's best to either verify this before trying
  741.     to create a transform with them (using this function), or catch the
  742.     potential PyCMSError that will occur if they don't support the modes
  743.     you select.
  744.  
  745.     """
  746.     try:
  747.         if not isinstance(profile, ImageCmsProfile):
  748.             profile = ImageCmsProfile(profile)
  749.         # FIXME: I get different results for the same data w. different
  750.         # compilers.  Bug in LittleCMS or in the binding?
  751.         if profile.profile.is_intent_supported(intent, direction):
  752.             return 1
  753.         else:
  754.             return -1
  755.     except (AttributeError, IOError, TypeError, ValueError), v:
  756.         raise PyCMSError(v)
  757.  
  758. ##
  759. # (pyCMS) Fetches versions.
  760.  
  761. def versions():
  762.     import sys
  763.     return (
  764.         VERSION, core.littlecms_version, sys.version.split()[0], Image.VERSION
  765.         )
  766.  
  767. # --------------------------------------------------------------------
  768.  
  769. if __name__ == "__main__":
  770.     # create a cheap manual from the __doc__ strings for the functions above
  771.  
  772.     import ImageCms
  773.     import string
  774.     print __doc__
  775.  
  776.     for f in dir(pyCMS):
  777.         print "="*80
  778.         print "%s" %f
  779.  
  780.         try:
  781.             exec ("doc = ImageCms.%s.__doc__" %(f))
  782.             if string.find(doc, "pyCMS") >= 0:
  783.                 # so we don't get the __doc__ string for imported modules
  784.                 print doc
  785.         except AttributeError:
  786.             pass
  787.